<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>jQuery tablesorter 2.0 - Filter Widget External Search</title>

	<!-- jQuery -->
	<script src="js/jquery-latest.min.js"></script>

	<!-- Demo stuff -->
	<link class="ui-theme" rel="stylesheet" href="css/jquery-ui.min.css">
	<script src="js/jquery-ui.min.js"></script>
	<link rel="stylesheet" href="css/jq.css">
	<link href="css/prettify.css" rel="stylesheet">
	<script src="js/prettify.js"></script>
	<script src="js/docs.js"></script>

	<!-- Tablesorter: required -->
	<link rel="stylesheet" href="../css/theme.blue.css">
	<script src="../js/jquery.tablesorter.js"></script>
	<script src="../js/widgets/widget-storage.js"></script>
	<script src="../js/widgets/widget-filter.js"></script>

	<script id="js">$(function() {

	var $table = $('table').tablesorter({
		theme: 'blue',
		widgets: ["zebra", "filter"],
		widgetOptions : {
			// filter_anyMatch replaced! Instead use the filter_external option
			// Set to use a jQuery selector (or jQuery object) pointing to the
			// external filter (column specific or any match)
			filter_external : '.search',
			// add a default type search to the first name column
			filter_defaultFilter: { 1 : '~{query}' },
			// include column filters
			filter_columnFilters: true,
			filter_placeholder: { search : 'Search...' },
			filter_saveFilters : true,
			filter_reset: '.reset'
		}
	});

	// make demo search buttons work
	$('button[data-column]').on('click', function(){
		var $this = $(this),
			totalColumns = $table[0].config.columns,
			col = $this.data('column'), // zero-based index or "all"
			filter = [];

		// text to add to filter
		filter[ col === 'all' ? totalColumns : col ] = $this.text();
		$table.trigger('search', [ filter ]);
		return false;
	});

});</script>

</head>
<body>
<div id="banner">
	<h1>table<em>sorter</em></h1>
	<h2>Filter Widget External Search</h2>
	<h3>Flexible client-side table sorting</h3>
	<a href="index.html">Back to documentation</a>
</div>
<div id="main">

	<p></p>
	<br>
	<div class="accordion">

		<h3><a href="#">Notes</a></h3>
		<div>
		<ul>
			<li>In <span class="version updated">v2.26.2</span>, The not match (<code>!</code>) limitation is no longer in place. Try searching in the "Match any column" for <button type="button" data-column="all">!aaron</button>.</li>
			<li>In <span class="version">v2.22.0</span>, AnyMatch searches for specific columns will no longer save filter data to each targeted column. See the "AnyMatch Searches" section below.</li>
			<li>In <span class="version">v2.20.0</span>, <a href="https://github.com/MaksimProgr">@MasksimProgr</a> added a method to allow targeting a specific column using the anyMatch filter. Find more details in the AnyMatch section below.</li>
			<li>In <span class="version">v2.18.0</span>, the external search data column can be set to multiple columns (<code>data-column="0-2,4,6-7"</code>). Please see the <a href="example-widget-filter-external-inputs.html">Filter Widget External Inputs</a> demo for more details.</li>
			<li>In <span class="version">v2.17.8</span>, added a default fuzzy search to the "First Name" column.</li>
			<li>This is a demo of the <a href="index.html#widget-filter-external"><code>filter_external</code></a> option (added <span class="version">v2.15</span>).</li>
			<li>In <span class="version">v2.15</span>
				<ul>
					<li>The <a class="alert" href="index.html#widget-filter-any-match"><code>filter_anyMatch</code></a> option has been <span class="label alert">removed</span> (added <span class="version">v2.13.3</span>; removed in v2.15)</li>
					<li>A new option <code>filter_external</code> has been added. It is set to a jQuery selector string (<code>'.search'</code>) or jQuery object (<code>$('.search')</code>) targeting an external input.</li>
					<li>So now a table can include <em>both</em> a filter row (<code>filter_columnFilters</code> is <code>true</code>, i.e. the internal table filters) and any number of external search inputs (as set by the <code>filter_external</code> option).</li>
					<li>The external search results must have a <code>data-column="#"</code> attribute set, where <code>#</code> is the index of the column (zero-based) that the input targets, to have an input search all table content, set the data column attribute to <code>"all"</code> to match any column.</li>
					<li>The <a href="index.html#function-bindsearch"><code>$.tablesorter.bindSearch</code> function</a> (<a href="example-widget-filter-external-inputs.html">see demo</a>) does exactly the same thing as the <code>filter_external</code> option. The major difference is seen when using ajax to populate the table, the initial filter values can be set before tablesorter initialization when using the <code>filter_external</code> option; whereas, the bind search function can not set initial filter values and is usually executed after tablesorter initialization.</li>
				</ul>
			</li>
		</ul>
		</div>

		<h3><a href="#">AnyMatch Searches</a></h3>
		<div>
		<ul>
			<li>In <span class="version">v2.20.0</span>, the anyMatch filter can target specific columns using the following format:
				<pre class="prettyprint lang-js">#:{query}</pre>
				<ul>
					<li>where <code>#</code> is the column <strong>one-based index</strong> (non-developers count from one)</li>
					<li>and <code>{query}</code> is the specific column query.</li>
				</ul>
				<br>
				You can disable this type of search by setting the new <code>filter_columnAnyMatch</code> option to <code>false</code>.
				<h4>Examples</h4>
				<ul>
					<li><button type="button" data-column="all">4:&gt;30</button> Find values &gt; 30 in the age column</li>
					<li><button type="button" data-column="all">2:aa</button> Include a fuzzy search (see <code>filter_defaultFilter</code> setting) and look for "aa" in the first name column (four results should show).</li>
					<li><button type="button" data-column="all">1:5 && 7:12</button> Find ranks with a "5" in them and find dates with a "12" </li>
					<li>This column specific anyMatch does not support using an OR column search like <code>1:5|7:12</code> </li>
				</ul>
				<p></p>
				<span class="label label-info">* NOTE *</span> Fixed in <span class="version">v2.22.0</span>. <del>When a AnyMatch search of this type is active, it adds filter queries to specific columns, so if the filters are saved and you reload the page, the specified <em>column filters will become populated</em> along with the AnyMatch search</del>.
			</li>
		</ul>
		</div>

		<h3><a href="#">Limitations</a></h3>
		<div>
		<ul>
			<li>The any-match search method has limitations applied. It does not support all of the per column search features! So, at this time, the following types of queries are not allowed as the results will cause confusion:
				<ul>
					<li>Search operators - A search for values equal, greater or less than values (<code>&gt; &gt;= &lt;= &lt;</code>) is not allowed because tables that contain both numbers and text (in separate columns). For example:
						<pre class="prettyprint lang-javascript">&quot;Fred&quot; > &quot;1&quot;  // true*
&quot;Fred&quot; &lt; &quot;10&quot; // false
&quot;Fred&quot; &gt; 1    // false (numeric comparisons occur with parsed table data)
&quot;Fred&quot; &gt; 1    // false
&quot;Fred&quot; &lt; 10   // false</pre>* For comparisons, letters have a greater <a href="http://en.wikipedia.org/wiki/Ascii#ASCII_printable_characters">ASCII value</a> than numbers.
					</li>
					<li>Range query - A search for any number range (<code>1 - 10</code>) is not allowed because, if any columns contain text, then no rows will result. The examples are the same as the search operators examples above.</li>
					<li>Allowed filters include plain text matching, fuzzy search (<code>~</code>), exact match (<code>&quot;</code>), wild card matches( <code>?</code> or <code>*</code>), regex (<code>/\d/g</code>), and logical and (<code>a &amp;&amp; b</code>)/or (<code>a|b</code>) matches.<br><br></li>

					<li>Not Match query - <strong>No longer a limitation!</strong> (<span class="version updated">v2.26.2</span>)
						<p>Try searching for <button type="button" data-column="all">!aaron</button></p>
						<del>A search for not matches (<code>!a</code>) is not allowed because tables that contain both numbers and text (in separate columns) will always show all rows. For example:
						<pre class="prettyprint lang-javascript">&quot;Frank&quot;.search(&quot;a&quot;)    //  2 (a match, so this row "may" be hidden)
&quot;Fred&quot;.search(&quot;a&quot;)      // -1 (a not match! so this row will always show)
&quot;25&quot;.search(&quot;a&quot;)        // -1 (a not match! so this row will always show)
&quot;1/1/2014&quot;.search(&quot;a&quot;)  // -1 (a not match! so this row will always show)</pre></del>
					</li>

				</ul>
				</li>
				<li>Setting this option should work properly with or without the column filters. The only issue you would have is if you triggered a search on the table using an array with undefined or null array values, like this:
					<pre class="prettyprint lang-javascript">// apply "2?%" filter to the fifth column (zero-based index)
var columns = [];
columns[5] = '2?%';
// anyMatch will kick in on undefined column filters,
// unless the array looks like this: columns = [ '', '', '', '', '', '2?%' ]
$('table').trigger('search', [ columns ]);</pre>
				</li>
		</ul>
		</div>
	</div>
	<br>

	<h1>Demo</h1>

	<div id="demo"><input class="search" type="search" data-column="all"> (Match any column)<br>
<input class="search" type="search" data-column="1"> (First Name; fuzzy search... try "be")<br>

<!-- targeted by the "filter_reset" option -->
<button type="button" class="reset">Reset Search</button>

<table class="tablesorter">
	<thead>
		<tr>
			<th>Rank</th>
			<th data-placeholder="Fuzzy search">First Name</th>
			<th>Last Name</th>
			<th>Age</th>
			<th>Total</th>
			<th>Discount</th>
			<th>Date</th>
		</tr>
	</thead>
	<tbody>
		<tr><td>1</td><td>Philip Aaron</td><td>Johnson Sr Esq</td><td>25</td><td>$5.95</td><td>22%</td><td>Jun 26, 2004 7:22 AM</td></tr>
		<tr><td>11</td><td>Aaron</td><td>Hibert</td><td>12</td><td>$2.99</td><td>5%</td><td>Aug 21, 2009 12:21 PM</td></tr>
		<tr><td>12</td><td>Brandon Clark</td><td>Henry Jr</td><td>51</td><td>$42.29</td><td>18%</td><td>Oct 13, 2000 1:15 PM</td></tr>
		<tr><td>111</td><td>Peter</td><td>Parker</td><td>28</td><td>$9.99</td><td>20%</td><td>Jul 6, 2006 8:14 AM</td></tr>
		<tr><td>21</td><td>John</td><td>Hood</td><td>33</td><td>$19.99</td><td>25%</td><td>Dec 10, 2002 5:14 AM</td></tr>
		<tr><td>013</td><td>Clark</td><td>Kent Sr.</td><td>18</td><td>$15.89</td><td>44%</td><td>Jan 12, 2003 11:14 AM</td></tr>
		<tr><td>005</td><td>Bruce</td><td>Almighty Esq</td><td>45</td><td>$153.19</td><td>44%</td><td>Jan 18, 2021 9:12 AM</td></tr>
		<tr><td>10</td><td>Alex</td><td>Dumass</td><td>13</td><td>$5.29</td><td>4%</td><td>Jan 8, 2012 5:11 PM</td></tr>
		<tr><td>16</td><td>Jim</td><td>Franco</td><td>24</td><td>$14.19</td><td>14%</td><td>Jan 14, 2004 11:23 AM</td></tr>
		<tr><td>166</td><td>Bruce Lee</td><td>Evans</td><td>22</td><td>$13.19</td><td>11%</td><td>Jan 18, 2007 9:12 AM</td></tr>
		<tr><td>100</td><td>Brenda Lee</td><td>McMasters</td><td>18</td><td>$55.20</td><td>15%</td><td>Feb 12, 2010 7:23 PM</td></tr>
		<tr><td>55</td><td>Dennis</td><td>Bronson</td><td>65</td><td>$123.00</td><td>32%</td><td>Jan 20, 2001 1:12 PM</td></tr>
		<tr><td>9</td><td>Martha</td><td>delFuego</td><td>25</td><td>$22.09</td><td>17%</td><td>Jun 11, 2011 10:55 AM</td></tr>
	</tbody>
</table></div>

	<h1>Javascript</h1>
	<div id="javascript">
		<pre class="prettyprint lang-javascript"></pre>
	</div>

	<h1>HTML</h1>
	<div id="html">
		<pre class="prettyprint lang-html"></pre>
	</div>

<div class="next-up">
	<hr />
	Next up: <a href="example-widget-filter-external-inputs.html">jQuery custom filter widget external inputs &rsaquo;&rsaquo;</a>
</div>

</div>

</body>
</html>
